package org.balthie.demo.jdk.util.concurrent.auxiliary.forkjoin;

import org.springframework.util.StopWatch;

public class ThreadBaseDemo {
	final static Object obj = new Object();
	static StopWatch sw = new StopWatch();

	public static void main(String[] args) throws Exception {
		// wait(),notify(),notifyall() 必须在同步代码块（sync）中使用，在执行前必须获取 锁定对象的锁（ ObjectMonitor 给对象头加锁）
//		exceptionNoSync();

		withSync();
		
		// 睡眠一秒钟，保证子线程已经计算完成，阻塞在wait方法
		sw.start("sleep 1s");
		Thread.sleep(1000);
		sw.stop();
		
		sw.start("notify all");
		synchronized (obj) {
			obj.notifyAll();
		}
		sw.stop();
		System.out.println(sw.prettyPrint());
	}

	private static void withSync() throws InterruptedException {
		sw.start("start 子线程");
		//	100个子县城，分布计算	
		for(int t=0; t<100;t++) {
			Thread A = new Thread(() -> {
				int sum = 0;
				for (int i = 0; i < 10; i++) {
					sum += i;
				}
				try {
					synchronized (obj) {
						System.out.println(Thread.currentThread() + " wait ");
						obj.wait();
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread() + " print sum: " + sum);
			});
			A.start();
		}
		sw.stop();
	}

	// Exception in thread "main" java.lang.IllegalMonitorStateException: current
	// thread is not owner
	// at java.base/java.lang.Object.notify(Native Method)
	// at
	// org.balthie.demo.jdk.thread.demo.ThreadBaseDemo.main(ThreadBaseDemo.java:22)
	private static void exceptionNoSync() throws InterruptedException {
		Thread A = new Thread(() -> {
			System.out.println(Thread.currentThread() + " run ");
			int sum = 0;
			for (int i = 0; i < 10; i++) {
				sum += i;
			}
			try {
				System.out.println(Thread.currentThread() + " wait ");
				obj.wait();
			} catch (Exception e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread() + " print sum: " + sum);
		});
		A.start();
	}
}
